package cn.xx.user.service.impl;

import cn.xx.basic.constant.PetHomeConstant;
import cn.xx.basic.constant.VerifactionCodeConstant;
import cn.xx.basic.service.impl.BaseServiceImpl;
import cn.xx.basic.exception.CustomException;
import cn.xx.basic.util.MD5Utils;
import cn.xx.basic.util.StrUtils;
import cn.xx.user.domain.LoginInfo;
import cn.xx.user.domain.User;
import cn.xx.user.dto.UserDto;
import cn.xx.user.mapper.LoginInfoMapper;
import cn.xx.user.mapper.UserMapper;
import cn.xx.user.service.IUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LoginInfoMapper loginInfoMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void checkPhone(String phone) throws CustomException {
        // 获取对象
        User user = userMapper.checkPhone(phone);
        // 如果存在代表手机号重复
        if (user != null) {
            // 抛出异常信息
            throw new CustomException("手机已经存在！");
        }
    }






    /**
     * 校验前端传递的数据
     * 检查注册的信息
     * @param userDto
     * @throws CustomException
     */
    @Override
    public void register(UserDto dto) throws CustomException {
        // 检查数据
        checkData(dto);
        // 传入dto创建user对象
        User user = userDto2User(dto);
        // 根据user对象创建login对象
        LoginInfo loginInfoByUser = createLoginInfoByUser(user);
        // 保存loginInfo
        loginInfoMapper.save(loginInfoByUser);
        // 保存user
        userMapper.save(user);
        // 设置loginInfo对象
        user.setLoginInfo(loginInfoByUser);
        // 更新修改
        userMapper.update(user);
    }

    /**
     * 创建User对象
     * @param userDto
     * @return
     */
    @Override
    public User userDto2User(UserDto dto) {
        // 新建user对象
        User user = new User();
        // 设置手机号
        user.setPhone(dto.getPhone());
        // 盐值：动态生成的 盐值随机生成10位
        user.setSalt(StrUtils.getComplexRandomString(10));
        // 设置密码调用MD5工具类方法 密码+随机生成的盐值
        user.setPassword(MD5Utils.encrypByMd5(dto.getPassword()+user.getSalt()));
        // 返回设置好的user对象
        return user;
    }


    /**
     * 创建LoginInfo对象
     * @param user
     * @return
     */
    @Override
    public LoginInfo createLoginInfoByUser(User user) {
        // 新建登录信息表对象
        LoginInfo loginInfo = new LoginInfo();
        // 复制user对象信息到loginInfo
        BeanUtils.copyProperties(user, loginInfo);
        // 手动设置登录类型为Home   商家/用户
        loginInfo.setType(PetHomeConstant.HOME);
        // loginInfo
        return loginInfo;
    }


    private void checkData(UserDto dto) throws CustomException {
        // user表中检查手机是否重复
        checkPhone(dto.getPhone());

        if(StringUtils.isEmpty(dto.getPhone())) {
            throw new CustomException("手机号不可以为空！");
        }
        // logininfo表中查询手机号和对应的平台(用户/商家)是否重复
        LoginInfo loginInfo = loginInfoMapper.checkPhoneAndType(dto.getPhone(), PetHomeConstant.HOME);
        if (loginInfo != null) {
            throw new  CustomException("手机号已被注册！");
        }

        // 检查验证码是否为空
        if(StringUtils.isEmpty(dto.getCode())) {
            throw new CustomException("验证码不可以为空！");
        }
        // 获取验证码
        String redisCode = (String)redisTemplate.opsForValue().get(dto.getPhone() + ":" + VerifactionCodeConstant.REG_CODE);
        String code = redisCode.split(":")[0];
        // 验证码超过5分钟后失效
        if(code==null) {
            throw new CustomException("验证码已经失效！");
        }
        // 输入不正确的验证码报错
        if (!code.equals(dto.getCode())) {
            throw new CustomException("验证码输入错误！");
        }


        if(StringUtils.isEmpty(dto.getPassword())) {
            throw new CustomException("密码不可以为空！");
        }

        if(StringUtils.isEmpty(dto.getConfigPassword())) {
            throw new CustomException("确认密码不可以为空！");
        }
        // 两次密码不一致
        if (!dto.getPassword().equals(dto.getConfigPassword())) {
            throw new CustomException("两次密码输入不一致！");
        }
    }


}
